package com.xb.loan.usercenter.user.user.service.impl;

import com.xb.loan.log.exception.BizException;
import com.xb.loan.usercenter.service.user.ISessionService;
import com.xb.loan.usercenter.service.user.bean.LoginInfoVO;
import com.xb.loan.usercenter.service.user.bean.UserSessionIdBakVO;
import com.xb.loan.util.cache.DefaultCacheFactory;
import com.xb.loan.util.log.DefaultLoggerFacotry;
import com.xb.loan.util.log.LogFormatUtil;
import org.slf4j.Logger;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.UUID;

@Service("sessionService")
public class RedisSessionServiceImpl implements ISessionService {

    Logger logger = DefaultLoggerFacotry.getLogger(RedisSessionServiceImpl.class);
    
	public boolean clearUserInfoCache(String sessionId) throws BizException {
		
		return DefaultCacheFactory.getFacotry().getCache().removeBean(LoginInfoVO.class,sessionId);
	}

	public boolean checkLogin(LoginInfoVO loginInfoVO) throws BizException {
		
		String userId = loginInfoVO.getUserId();
		long tokenEffTime = loginInfoVO.getTokenEffective().getTime();
		//long expiredTime = loginInfoVO.getExpiredTime();
		long currentTime = System.currentTimeMillis();
		
		logger.info(LogFormatUtil.getFormatTemplate(new String[]{"用户","访问时间","token过期时间","当前时间","sessionId"}),
				new Object[]{userId,"",
									new Date(tokenEffTime)+"-->"+(tokenEffTime),
									new Date(currentTime)+"-->"+currentTime,loginInfoVO.getSessionId()});
		if(tokenEffTime<currentTime){
			
			logger.info(LogFormatUtil.getFormatTemplate(new String[]{"用户","清除会话"}),
					new Object[]{userId,loginInfoVO.getSessionId()});
			//过期自动退出
			logger.info(LogFormatUtil.getFormatTemplate(new String[]{"module","userId","time"}),
			new Object[]{"Notice:RedisSessionServiceImpl.checkLogin clearUserInfoCache","userId",new Date()});

			this.clearUserInfoCache(loginInfoVO.getSessionId());
			this.clearUserSessionIdBakVO(userId);

			return false;
		}
		//更新用户登录时间
		loginInfoVO.setLastAccessTime(new Date());
		this.updateUserInfoCache(loginInfoVO);
		return true;
	}
	
	public LoginInfoVO queryUserInfoCacheOnly(String sessionId) throws BizException {

		return DefaultCacheFactory.getFacotry().getCache().getBean(LoginInfoVO.class,sessionId);
	}
	
	public LoginInfoVO queryUserInfoCache(String sessionId) throws BizException {

		LoginInfoVO loginInfoVO = this.queryUserInfoCacheOnly(sessionId);
		
		logger.info(LogFormatUtil.getFormatTemplate(new String[]{"module","sessionId","userId","loginInfoVO is "}),
				new Object[]{"Notice:RedisSessionServiceImpl.queryUserInfoCache",sessionId,
					loginInfoVO == null ? "loginInfoVO is null" : loginInfoVO.getUserId(),loginInfoVO});
		if(loginInfoVO != null && checkLogin(loginInfoVO)){
			
			//在有效期
			return loginInfoVO;
		}
		return null;
	}

	public String insertUserInfoCache(LoginInfoVO loginInfoVO) throws BizException {
		
		//生成sessionId同时更新loginInfoVO
		generateSessionId(loginInfoVO);
		DefaultCacheFactory.getFacotry().getCache().setBean(LoginInfoVO.class,loginInfoVO.getSessionId(),loginInfoVO);
		
		//新增备份记录新的UserId和SessionId映射关系
		UserSessionIdBakVO userSessionIdBakVO = new UserSessionIdBakVO();
		userSessionIdBakVO.setUserId(loginInfoVO.getUserId());
		userSessionIdBakVO.setSessionId(loginInfoVO.getSessionId());
		this.updateUserSessionIdBakVO(userSessionIdBakVO);
		
//		boolean loginFlag = DefaultCacheFactory.getFacotry().getCache().setBean(LoginInfoVO.class,loginInfoVO.getSessionId(),loginInfoVO);
//		boolean bakFlag = this.updateUserSessionIdBakVO(userSessionIdBakVO);
//		if(loginFlag && !bakFlag){
//			boolean clearLoginFlag = this.clearUserInfoCache(loginInfoVO.getSessionId());
//			if(!clearLoginFlag){
//				logger.info(LogFormatUtil.getFormatTemplate(new String[]{"module","clearLoginFlag","sessionId"}),
//						new Object[]{"Notice:RedisSessionServiceImpl.insertUserInfoCache clearLoginFlag failure",clearLoginFlag,loginInfoVO.getSessionId()});
//			}
//		}
//		
//		if(!loginFlag || !bakFlag){
//			logger.info(LogFormatUtil.getFormatTemplate(new String[]{"module","loginFlag","bakFlag","sessionId"}),
//					new Object[]{"Notice:RedisSessionServiceImpl.insertUserInfoCache failure",loginFlag,bakFlag,loginInfoVO.getSessionId()});
//			throw IUserServiceException.notlogin;
//		}

		return loginInfoVO.getSessionId();
	}
	
	public String insertUserInfoCacheOnly(LoginInfoVO loginInfoVO) throws BizException {
		
		//生成sessionId同时更新loginInfoVO
		generateSessionId(loginInfoVO);
		DefaultCacheFactory.getFacotry().getCache().setBean(LoginInfoVO.class,loginInfoVO.getSessionId(),loginInfoVO);
		
//		boolean loginFlag = DefaultCacheFactory.getFacotry().getCache().setBean(LoginInfoVO.class,loginInfoVO.getSessionId(),loginInfoVO);
//		if(!loginFlag){
//			logger.info(LogFormatUtil.getFormatTemplate(new String[]{"module","loginFlag","sessionId"}),
//					new Object[]{"Notice:RedisSessionServiceImpl.insertUserInfoCacheOnly failure",loginFlag,loginInfoVO.getSessionId()});
//			return null;
//		}
		
		return loginInfoVO.getSessionId();
	}

	public boolean updateUserInfoCache(LoginInfoVO loginInfoVO) throws BizException {
		
		return DefaultCacheFactory.getFacotry().getCache().setBean(LoginInfoVO.class,loginInfoVO.getSessionId(),loginInfoVO);
	}
	
	public String generateSessionId(LoginInfoVO loginInfoVO) throws BizException{
		String token = loginInfoVO.getToken();
		if(token != null && token.length() > 0){
			loginInfoVO.setSessionId(token);
			return token;
		}else{
			String prefix = new StringBuffer("")
					.append(new SimpleDateFormat("hhmmssSSS").format(new Date()) + "-")
					.append(new Random().nextInt(1000000)).toString();
			String uuidStr = prefix + "_" + UUID.randomUUID().toString();
			loginInfoVO.setSessionId(uuidStr);
			return uuidStr;
		}
	}

	@Override
	public UserSessionIdBakVO queryUserSessionIdBakVO(String userId)
			throws BizException {

		return DefaultCacheFactory.getFacotry().getCache().getBean(UserSessionIdBakVO.class,userId);
	}

	@Override
	public boolean insertUserSessionIdBakVO(
			UserSessionIdBakVO userSessionIdBakVO) throws BizException {

		return DefaultCacheFactory.getFacotry().getCache().setBean(UserSessionIdBakVO.class,userSessionIdBakVO.getUserId(),userSessionIdBakVO);
	}

	@Override
	public boolean updateUserSessionIdBakVO(
			UserSessionIdBakVO userSessionIdBakVO) throws BizException {

		return DefaultCacheFactory.getFacotry().getCache().setBean(UserSessionIdBakVO.class,userSessionIdBakVO.getUserId(),userSessionIdBakVO);
	}

	@Override
	public boolean clearUserSessionIdBakVO(String userId) throws BizException {

		return DefaultCacheFactory.getFacotry().getCache().removeBean(UserSessionIdBakVO.class,userId);
	}
	
}
